import { message, notification } from 'antd';
import type { ResponseError } from 'umi-request';
import { extend } from 'umi-request';
import type { RequestFunctionParams } from 'yapi-to-typescript';
import { RequestBodyType } from 'yapi-to-typescript';
// import mockURLs from './mockURLs';
import type { RequestOptionsInit } from 'umi-request/types/index';


/** 后端必须设置对应的请求头；\
 * 另外因为发起的是fetch请求不是常规的get，需要手动对返回值进行处理（无浏览器默认下载动作）
 * content-disposition: attachment;filename=xxxxxxx.pdf
    content-length: 79959
    content-type: application/pdf;charset=utf-8
 */
const downloadFile = ({ blob, url }: { blob?: Blob; url?: URL }, fileName?: string) => {
  console.log(blob);

  const _url = `${url || (blob ? window.URL.createObjectURL(blob) : '')}`;

  const link = document.createElement('a');
  link.style.display = 'none';
  link.href = _url;
  link.target = '_blank';

  if (fileName) link.setAttribute('download', fileName);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(_url);
};
export interface RequestOptions {
  /**
   * 是否返回 Blob 结果，适用某些返回文件流的接口。
   */
  returnBlob?: boolean;
  isLoading?: boolean;
  headers?: HeadersInit;
  fileName?: string;
}
message.config({
  top: 100,
});

/**
 * 异常处理程序
 */
const errorHandler = async (error: ResponseError): Promise<Response> => {
  console.log('errorHandler', error);

  const { response } = error;
  message.destroy();
  if (response?.status) {
    if (response.status === 403 && process.env.B_ENV === 'prod') {
      window.location.replace(process.env.SSO_LOGIN_URL as string);
    }
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常，无法连接服务器',
      message: '网络异常',
    });
  }
  return Promise.reject(response);
};

/**
 * 自定义接口使用此对象请求
 */

export const requestObj = extend({
  // prefix,
  timeout: 20000,
  errorHandler,
});

// 请求前拦截
requestObj.interceptors.request.use((url: string, options: RequestOptionsInit) => {
  const client = window.localStorage.getItem('client') || '';
  const reqUrl: string = options.url.startsWith('http') ? options.url : url;

  return {
    url: reqUrl.replace(/{client}/g, client),
    options,
  };
});

/**
 * yapi的接口会调用此函数，其他情况无需使用
 */
export default async function request<TResponseData>(
  payload: RequestFunctionParams,
  options?: RequestOptions,
): Promise<TResponseData> {
  // console.log(payload);

  const { path } = payload;
  const key = `loading${path}`;
  if (options?.isLoading) {
    message.loading({ content: '加载中...', key, duration: 0 });
  }
  try {
    // console.log(payload.rawData);

    // 配置mockURLs之后
    // console.log(mockURLs, path);
    // if (process.env.NODE_ENV === 'development' && Array.isArray(mockURLs)) {
    //   if (mockURLs.some((url: string) => path.startsWith(url))) {
    //     path = new URL(payload.mockUrl).pathname + path;
    //   }
    //   // } else {
    //   //   // 处理url上的{client}参数
    //   //   path = path.replace(/\{client\}/, window.localStorage.getItem('client') || 'org');
    // }

    const { data, response } = await requestObj(path, {
      isLoading: options?.isLoading,
      getResponse: true,
      method: payload.method,
      headers: {
        token: String(window.localStorage.getItem('token') || ''),
        ...options?.headers,
      },
      data:
        // eslint-disable-next-line no-nested-ternary
        payload.requestBodyType === RequestBodyType.form || payload.hasFileData
          ? payload.getFormData()
          : payload.requestBodyType === RequestBodyType.json
          ? payload.data
          : {},
      // 相关的params参数已经提前被加到payload.path了
      // params: payload.requestBodyType === RequestBodyType.query ? payload.data : {},
    });

    // console.log('response', response);

    if (options?.isLoading) message.destroy(key);

    // 返回json
    if (data?.code >= 200 && data?.code < 300) {
      // console.log('code === 200', data.data);
      return data.data;
    }
    if (data?.code >= 300) {
      message.error(data?.msg || data?.message);
      if (data?.code === 5001 || data?.code === 501) {
        window.location.replace(process.env.SSO_LOGIN_URL as string);
      }
      return Promise.reject(data);
    }

    // 下载文件
    if (options?.returnBlob) {
      const fileName = decodeURI(
        `${response.headers.get('content-disposition')}`.replace(/.+filename=(.+)/, '$1'),
      );
      downloadFile({ blob: await response.blob() }, fileName);
      return data as unknown as TResponseData;
    }

    return data;
  } catch (error) {
    return Promise.reject(error);
  }
}
